package com.regulareport.quartz.task;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.regulareport.common.core.domain.entity.ReportCellDefinition;
import com.regulareport.common.core.domain.entity.ReportFormsEdit;
import com.regulareport.common.enums.*;
import com.regulareport.common.utils.poi.ExcelToJsonConverter;
import com.regulareport.common.utils.spring.SpringUtils;
import com.regulareport.form.domain.ReportVerificationConfigTemp;
import com.regulareport.form.mapper.ReportCellDefinitionMapper;
import com.regulareport.form.mapper.ReportFormsEditMapper;
import com.regulareport.form.mapper.ReportVerificationConfigTempMapper;
import com.regulareport.form.service.IReportFormsEditService;
import com.regulareport.quartz.domain.ReportPlanA;
import com.regulareport.quartz.domain.ReportTaskA;
import com.regulareport.quartz.mapper.ReportPlanAMapper;
import com.regulareport.quartz.mapper.ReportTaskAMapper;
import org.apache.poi.ss.util.CellAddress;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.regulareport.common.utils.StringUtils;

import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAdjusters;
import java.util.*;

import com.fasterxml.jackson.core.type.TypeReference;
import com.regulareport.common.core.redis.RedisCache;
import org.springframework.util.CollectionUtils;

import java.io.ByteArrayInputStream;
import java.io.InputStream;

/**
 * 定时任务调度测试
 *
 * @author ruoyi
 */
@Component("ryTask")
public class RyTask {
    @Autowired
    private ReportPlanAMapper reportPlanAMapper;
    @Autowired
    private ReportTaskAMapper reportTaskMapper;
    @Autowired
    private ReportCellDefinitionMapper reportCellDefinitionMapper;

    public void ryMultipleParams(String s, Boolean b, Long l, Double d, Integer i) {
        System.out.println(StringUtils.format("执行多参方法： 字符串类型{}，布尔类型{}，长整型{}，浮点型{}，整形{}", s, b, l, d, i));
    }

    public void ryParams(String params) {
        System.out.println("执行有参方法：" + params);
    }

    public void ryNoParams() {
        System.out.println("执行无参方法");
    }

    public void delivery() {
        ReportPlanA reportPlan = new ReportPlanA();
        reportPlan.setEnable(EnableStatus.OK.getCode());
        reportPlan.setDelFlag(DelFlag.NORMAL.getCode());
        reportPlan.setDeliveryType(DeliveryType.AUTO.getCode());
        reportPlan.setDeliveryStatus(DeliveryStatus.DELIVERY.getCode());
        List<ReportPlanA> reportPlans = reportPlanAMapper.selectDeliveryPlan(reportPlan);
        LocalDate currentDate = LocalDate.now();
        List<ReportTaskA> reportTaskAS = new ArrayList<>();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd");
        for (ReportPlanA plan : reportPlans) {
            plan.setUpdateBy("SYSTEM");
            int deadLine = Integer.parseInt(plan.getDeadLine());
            int biasDay = Integer.parseInt(plan.getBiasDay());
            LocalDate handleD = LocalDate.of(currentDate.getYear(), currentDate.getMonth(), deadLine);
            for (int i = 0; i < 2; i++) {
                LocalDate localDate = handleD.plusMonths(i);
                LocalDate compareD = localDate.plusDays(-biasDay);
                if (FrequencyType.MONTH1.getCode() == plan.getFrequency() || FrequencyType.MONTH2.getCode() == plan.getFrequency()) {
                    if (currentDate.isEqual(compareD)) {
                        ReportTaskA reportTask = new ReportTaskA();
                        reportTask.setPlanId(plan.getPlanId());
                        reportTask.setTaskStatus(TaskStatus.DELIVERED.getCode());
                        reportTask.setTaskType(TaskType.AUTO.getCode());
                        reportTask.setCreateBy("SYSTEM");
                        reportTask.setDeadLine(Date.from(
                                handleD.atStartOfDay()              // 添加默认时间00:00:00
                                        .atZone(ZoneId.systemDefault())  // 指定系统默认时区
                                        .toInstant()                     // 转换为Instant
                        ));
                        LocalDate lastDayOfLastMonth = handleD.minusMonths(1)
                                .with(TemporalAdjusters.lastDayOfMonth());
                        reportTask.setDataDate(lastDayOfLastMonth.format(formatter));
                        reportTaskAS.add(reportTask);
                        break;
                    }
                } else if (FrequencyType.QUARTER1.getCode() == plan.getFrequency() || FrequencyType.QUARTER2.getCode() == plan.getFrequency()) {
                    if (handleD.getMonthValue() == 4 || handleD.getMonthValue() == 7 || handleD.getMonthValue() == 10 || handleD.getMonthValue() == 1) {
                        if (currentDate.isEqual(compareD)) {
                            ReportTaskA reportTask = new ReportTaskA();
                            reportTask.setPlanId(plan.getPlanId());
                            reportTask.setTaskStatus(TaskStatus.DELIVERED.getCode());
                            reportTask.setTaskType(TaskType.AUTO.getCode());
                            reportTask.setCreateBy("SYSTEM");
                            reportTask.setDeadLine(Date.from(
                                    handleD.atStartOfDay()              // 添加默认时间00:00:00
                                            .atZone(ZoneId.systemDefault())  // 指定系统默认时区
                                            .toInstant()                     // 转换为Instant
                            ));
                            LocalDate lastDayOfLastMonth = handleD.minusMonths(1)
                                    .with(TemporalAdjusters.lastDayOfMonth());
                            reportTask.setDataDate(lastDayOfLastMonth.format(formatter));
                            reportTaskAS.add(reportTask);
                            break;
                        }
                    }
                } else if (FrequencyType.HALF_YEAR.getCode() == plan.getFrequency()) {
//                deliveryPlan.add(plan);
                }
            }
        }

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        for (ReportTaskA reportTaskA : reportTaskAS) {
            ReportPlanA reportPlanA = new ReportPlanA();
            reportPlanA.setPlanId(reportTaskA.getPlanId());
            reportPlanA.setReportEndTime(sdf.format(reportTaskA.getDeadLine()));
            reportPlanA.setUpdateBy("SYSTEM");
            reportPlanAMapper.deliveryByID(reportPlanA);
            reportPlanAMapper.updateDeadLine(reportPlanA);
            reportTaskMapper.deliveryByPlanID(reportTaskA);
        }
    }

    public void creatIndexVerification() {
        System.out.println("开始执行creatIndexVerification方法 start................ ");

        ObjectMapper mapper = new ObjectMapper();

        IReportFormsEditService reportFormsEditService = SpringUtils.getBean(IReportFormsEditService.class);

        ReportCellDefinitionMapper reportCellDefinitionMapper = SpringUtils.getBean(ReportCellDefinitionMapper.class);

        ReportFormsEditMapper reportFormsEditMapper = SpringUtils.getBean(ReportFormsEditMapper.class);

        RedisCache redisCache = SpringUtils.getBean(RedisCache.class);

        ReportVerificationConfigTempMapper reportVerificationConfigTempMapper = SpringUtils.getBean(ReportVerificationConfigTempMapper.class);

        ReportFormsEdit reportFormsEdit = new ReportFormsEdit();
        List<ReportFormsEdit> reportFormsEditList = reportFormsEditMapper.selectRepFormsEditListForVerificationConfig(reportFormsEdit);
        for (ReportFormsEdit repForEd : reportFormsEditList) {
            String templateStr = "";
            //单元格定义转化
            try {
                byte[] templateByteArr = redisCache.getCacheObject(String.valueOf((repForEd.getReportFormNo() + "_" + repForEd.getEdition()).getBytes(StandardCharsets.UTF_8)));
                if (templateByteArr != null && templateByteArr.length > 0) {
                    templateStr = new String(templateByteArr, StandardCharsets.UTF_8);
                }
            } catch (Exception e) {
                e.printStackTrace();
                throw new RuntimeException("字符编码转换失败", e);
            }

            //如果缓存不存在从数据库查模板信息
            if (StringUtils.isEmpty(templateStr)) {
                //暂时用前台传过来的报表ID
                byte[] fileJsonArr = repForEd.getFileJson();
                InputStream input = new ByteArrayInputStream(fileJsonArr);
                try {
                    templateStr = ExcelToJsonConverter.convertExcelWithStyles(input);
                } catch (Exception e) {
                    e.printStackTrace();
                    throw new RuntimeException(e);
                }
            }
            Map templateMap;

            try {
                templateMap = mapper.readValue(templateStr, new TypeReference<Map<String, Object>>() {
                });
            } catch (JsonProcessingException e) {
                e.printStackTrace();
                throw new RuntimeException(e);
            }
            if (!CollectionUtils.isEmpty(templateMap)) {
                List<ReportCellDefinition> reportCellDefinitionList = new ArrayList<>();
                List<ReportVerificationConfigTemp> reportVerificationConList = new ArrayList<>();
                Map sheet1Map = (Map) templateMap.get("sheet1");
                Map rowsMap = (Map) sheet1Map.get("rows");
                int rowTotalNum = rowsMap.size();
                for (int rowNum = 0; rowNum < rowTotalNum; rowNum++) {
                    Map rowObject = (Map) rowsMap.get(String.valueOf(rowNum));
                    Map colsMap = (Map) rowObject.get("cells");
                    int colTotalNum = colsMap.size();
                    for (int colNum = 0; colNum < colTotalNum; colNum++) {
                        Map cellMap = (Map) colsMap.get(String.valueOf(colNum));
                        if (cellMap != null && cellMap.get("formula") != null && !cellMap.get("formula").equals("")) {
                            //获取公式
                            String formula = (String) cellMap.get("formula");
                            ReportCellDefinition reportCellDel = new ReportCellDefinition();

                            reportCellDel.setCellCol(String.valueOf(colNum));
                            reportCellDel.setCellRow(String.valueOf(rowNum));
                            reportCellDel.setReportFormID(repForEd.getPkId());
                            reportCellDel.setReportFormNo(repForEd.getReportFormNo());
                            reportCellDel.setFormula(formula);
                            reportCellDefinitionList.add(reportCellDel);
                        }
                    }
                }
                for (ReportCellDefinition definition : reportCellDefinitionList) {
                    ReportCellDefinition cellDef = reportCellDefinitionMapper.selectReportCellDefinitionByCompositeKeys(String.valueOf(definition.getReportFormID()), Integer.valueOf(definition.getCellRow()), Integer.valueOf(definition.getCellCol()));

                    ReportVerificationConfigTemp reportVerificationConfigTemp = new ReportVerificationConfigTemp();

                    reportVerificationConfigTemp.setDelFlag("0");
                    reportVerificationConfigTemp.setReportFormId(definition.getReportFormID());
                    reportVerificationConfigTemp.setReportFormName(repForEd.getReportFormName());
                    reportVerificationConfigTemp.setReportFormNo(definition.getReportFormNo());
                    reportVerificationConfigTemp.setVerificationType("01");
                    reportVerificationConfigTemp.setEffectiveSign("04");
                    String sourceFormula = definition.getFormula();
                    String handleFormula = expandSumFormula(definition.getFormula(), String.valueOf(repForEd.getPkId()));
                    reportVerificationConfigTemp.setVerificationFormula(definition.getFormula());
                    if (StringUtils.isNotEmpty(handleFormula)) {
                        reportVerificationConfigTemp.setVerificationDescribe(handleFormula);
                    }
                    if (cellDef != null) {
                        definition.setIndexNo(cellDef.getIndexNo());
                        definition.setIndexName(cellDef.getIndexName());
                        reportVerificationConfigTemp.setIndexNo(cellDef.getIndexNo());
                        reportVerificationConfigTemp.setIndexName(cellDef.getIndexName());
                        if (!sourceFormula.startsWith("=")) {
                            reportVerificationConfigTemp.setVerificationFormula(definition.getIndexNo() + "=" + definition.getFormula());
                        } else {
                            reportVerificationConfigTemp.setVerificationFormula(definition.getIndexNo() + definition.getFormula());
                        }
                        if (!sourceFormula.startsWith("=") && StringUtils.isNotEmpty(handleFormula)) {
                            reportVerificationConfigTemp.setVerificationDescribe(cellDef.getIndexName() + "=" + handleFormula);
                        } else if (StringUtils.isNotEmpty(handleFormula)) {
                            reportVerificationConfigTemp.setVerificationDescribe(cellDef.getIndexName() + handleFormula);
                        }
                        reportVerificationConfigTemp.setCoordinate(cellDef.getCoordinate());
                    }

                    reportVerificationConList.add(reportVerificationConfigTemp);

                }


                int result = 0;
                if (reportVerificationConList != null && reportVerificationConList.size() > 0) {
                    result = reportVerificationConfigTempMapper.batchInsertReportVerificationConfigTemp(reportVerificationConList);
                }
                System.out.println("报表编号： " + repForEd.getReportFormNo() + " ,  成功保存 ： " + result + " 条");
            }

        }

        System.out.println("creatIndexVerification方法执行结束 ................ end");

    }

    private String expandSumFormula(String formula, String reportFormId) {
        //只处理+ -法 不涉及 SUM  if  除/
        if (!formula.contains("SUM(") && !formula.contains("if(") && !formula.contains("/")) {
            // 分割并过滤空字符串
            String[] formulArr = Arrays.stream(formula.split("[=+-]"))
                    .filter(s -> !s.isEmpty())
                    .toArray(String[]::new);
            List<String> formulaList = Arrays.asList(formulArr);
            Map<String, String> indexNameMap = new HashMap();
            for (String addrStr : formulaList) {
                CellAddress address = new CellAddress(addrStr);
                int rowIndex = address.getRow(); // 返回7（第8行）
                int columnIndex = address.getColumn(); // 返回2（第3列）
                ReportCellDefinition repCellDef = reportCellDefinitionMapper.selectReportCellDefinitionByCompositeKeys(reportFormId, rowIndex, columnIndex);
                if (repCellDef != null) {
                    indexNameMap.put(addrStr, repCellDef.getIndexName());
                }
            }
            for (Map.Entry<String, String> entry : indexNameMap.entrySet()) {
                formula = formula.replace(entry.getKey().trim(), entry.getValue());
            }
        }
        return formula;
    }
}
